function send(content: string) {
  postMessage({
    time: new Date().getSeconds(),
    content: content
  })
}

onmessage = function (e) {
  const m = e.data[0]
  const n = e.data[1]
  console.log(m, n)
  setTimeout(() => {
    send('setTimeout start')
    for (let i = 0; i < m; i++) {
      if (i === m - 1) {
        send('setTimeout end')
      }
    }
  }, 0)
  send('game start')
  new Promise((resolve) => resolve('promise start')).then((res: any) => {
    send(res)
    for (let i = 0; i < n; i++) {
      if (i === n - 1) {
        send('promise end')
      }
    }
  })
}
// 上面的代码，是使用多线程加速
// 如果直接在js中执行，那么可以发现，在微任务执行完后，dom就更新了，而宏任务则在dom更新结束之后才继续执行。
/**
 * 很多人不知道的是，重绘和回流其实和 Event loop 有关

当 Event loop 执行完Microtasks 后，会判断 document 是否需要更新。因为浏览器是 60Hz 的刷新率，每 16ms 才会更新一次。
然后判断是否有 resize 或者 scroll ，有的话会去触发事件，所以 resize 和 scroll 事件也是至少 16ms才会触发一次，并且自带节流功能。
判断是否触发了 media query
更新动画并且发送事件
判断是否有全屏操作事件
执行 requestAnimationFrame 回调
执行 IntersectionObserver 回调，该方法用于判断元素是否可见，可以用于懒加载上，但是兼容性不好
更新界面
以上就是一帧中可能会做的事情。如果在一帧中有空闲时间，就会去执行 requestIdleCallback 回调
 */
